package com.csxh.web.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

public class Pager<T> {

	private int page;// 当前页号，从1开始
	private int size;// 每页记录数
	private int count;// 共多少页
	private long total;// 总记录数

	private String orderBy;//排序表达式
	private String condition;//分页条件表达式
	private Object[] params;//分页条件表达式中的参数
	
	private List<T> rowList = new ArrayList<T>();// 分页数据列表

	public Pager(long total, int size) {

		this.page = 1;
		this.total = total;
		this.size = size;
		this.count = (int) Math.ceil( (double)this.total / (double)this.size);
		
	}

	public Pager(long total, int size,String orderBy) {
		
		this.page = 1;
		this.total = total;
		this.size = size;
		this.count = (int) Math.ceil( (double)this.total / (double)this.size);
		this.orderBy=orderBy;
	}

	public Pager(long total, int size,String condition,Object...params) {
		
		this.page = 1;
		this.total = total;
		this.size = size;
		this.count = (int) Math.ceil( (double)this.total / (double)this.size);
		this.condition=condition;
	    this.params=params;
	}

	public Pager(long total, int size, String orderBy, String condition,Object...params) {
		
		this.page = 1;
		this.total = total;
		this.size = size;
		this.count = (int) Math.ceil( (double)this.total / (double)this.size);
		this.orderBy=orderBy;
		this.condition=condition;
		this.params=params;
	}

	
	// 页码
	public void setPage(int page) {
		this.page = page;
	}

	//获取当前页码
	public int getPage() {
		return this.page;
	}

	// 获取当前页的首记录在数据库表中的从0开始的偏移值
	public int getFirstRow() {
		return (this.page - 1) * this.size;
	}

	// 获取每页显示的记录数
	public int getSize() {
		return size;
	}

	// 总页码数
	public int getCount() {
		return count;
	}

	// 总记录数
	public long getTotal() {
		return total;
	}

	public List<T> getRowList() {
		return rowList;
	}

	public void setRowList(List<T> rowList) {
		this.rowList = rowList;
		
	}
	
	public void setOrderBy(String orderBy) {
		this.orderBy = orderBy;
	}
	
	public String getOrderBy() {
		return orderBy;
	}
	
	public void setCondition(String condition,Object...params){
		this.condition=condition;
		this.params=params;
		
	}
	
	public String getCondition() {
		return condition;
	}
	
	public Object[] getParams() {
		return params;
	}
	
	private String navUrl="";
	public void setNavUrl(String navUrl) {
		this.navUrl = navUrl;
	}
	
	//输出导航HTML
	public String getOutNavHtml(){
		
		StringBuffer sb=new StringBuffer();
		String conditionParam=this.serializeToRequestParam();
		
		sb.append("<nav>")
		      .append("<ul class='pager'>")
		          .append("<li>")
		             .append("<a href=")
		             .append(this.navUrl)
		             .append("?page=")
		             .append(1)
		             .append("&size=")
		             .append(this.size)
		             .append("&condition=").append(conditionParam)
		             .append(">最前页</a>");
		           if(this.page>1){
		        	  sb.append("<a href=")
		        	  .append(this.navUrl)
		        	  .append("?page=")
		        	  .append(this.page-1)
		        	  .append("&size=")
		        	  .append(this.size)
		        	  .append("&condition=").append(conditionParam)
		        	  .append(">上一页</a>");
		           }
		           if(this.page<this.count){
		        	   sb.append("<a href=")
		        	   .append(this.navUrl)
		        	   .append("?page=")
		        	   .append(this.page+1)
		        	   .append("&size=")
		        	   .append(this.size)
		        	   .append("&condition=").append(conditionParam)
		        	   .append(">下一页</a>");		        	   
		           }
		           sb.append("<a href=")
		           .append(this.navUrl)
		           .append("?page=")
		           .append(this.count)
		           .append("&size=")
		           .append(this.size)
		           .append("&condition=").append(conditionParam)
		           .append(">最后页</a>")
		          .append("</li>")
		      .append("</ul>")
          .append("</nav>");  
		           
		return sb.toString();
	}
	
	//输出分页信息
	public String getOutInfoHtml(){
		StringBuffer sb=new StringBuffer();
		sb.append("<span class='pull-right'>")
		  .append("<h4>当前第").append(this.page).append("页,共").append(this.count).append("页</h4>") 
		  .append("</span>");
		return sb.toString();
	}
	
	// 判断是否还有下一页
	public boolean isHasNext() {

		boolean b = this.page < this.count;
		return b;
	}

	// 判断是否还有上一页
	public boolean isHasPrev() {

		boolean b = this.page >1;
		return b;

	}

	// 定位到首页
	public boolean isFirst() {
		this.page = 1;
		return true;
	}

	// 定位到最后一页
	public boolean isLast() {
		this.page = this.count;
		return true;
	}

	// 定位到指定页码
	public int locate(int page) {
		
		if (page < 1)
			page = 1;
		if (page > this.count)
			page = this.count;
		this.page = page;
		
		return this.getFirstRow();
	}

	//将分页参数序列化请求参数
	public String serializeToRequestParam(){
		
		String requestParam="";
		if(null==this.condition || "".equals(this.condition)){
			return requestParam;
		}else{
			
			if(this.orderBy==null){
				this.orderBy="";
			}
			
			ByteArrayOutputStream bos=null;
			ObjectOutputStream oos=null;
			
			try {
				bos=new ByteArrayOutputStream();
				oos=new ObjectOutputStream(bos);
			
				oos.writeObject(this.orderBy);
				oos.writeObject(this.condition);
				ArrayList<Object> aList=new ArrayList<Object>();
				for(Object param : this.params){					
					aList.add(param);
				}
				oos.writeObject(aList);
			    oos.flush();
			    
				byte[] bs=bos.toByteArray();
			    
				String s=Base64.getUrlEncoder().encodeToString(bs);
				
			    requestParam+=s;
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				try {
					if(oos!=null){						
						oos.close();
					}
					if(bos!=null){						
						bos.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		return requestParam;
		
	}
	
	public void unSerializeFromRequestParam(String conditionRequestParam){
		if(null!=conditionRequestParam && conditionRequestParam.length()>0){
			ByteArrayInputStream bis=null;
			ObjectInputStream ois=null;
			try {
				
				byte[] bs=Base64.getDecoder().decode(conditionRequestParam);
				
				bis=new ByteArrayInputStream(bs);
				ois=new ObjectInputStream(bis);
				this.orderBy=(String)ois.readObject();
				this.condition=(String)ois.readObject();
				@SuppressWarnings("unchecked")
				ArrayList<Object> aList=(ArrayList<Object>)ois.readObject();
				this.params=aList.toArray();
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				try {
					if(ois!=null){						
						ois.close();
					}
					if(bis!=null){						
						bis.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	@Override
	public String toString() {
		return "Pager [page=" + page + ", size=" + size + ", count=" + count + ", total=" + total + "]";
	}
	
}
